home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 7 / Amiga Format AFCD07 (Dec 1996, Issue 91).iso / serious / shareware / programming / aros / utility / smult32.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-12  |  2.4 KB  |  107 lines

  1. /*
  2.     $Id: smult32.c,v 1.1 1996/08/31 12:58:13 aros Exp $
  3.     $Log: smult32.c,v $
  4.     Revision 1.1  1996/08/31 12:58:13  aros
  5.     Merged in/modified for FreeBSD.
  6.  
  7.     Desc:
  8.     Lang: english
  9. */
  10. #include "utility_intern.h"
  11.  
  12. /*****************************************************************************
  13.  
  14.     NAME */
  15.         #include <clib/utility_protos.h>
  16.  
  17.         __AROS_LH2(LONG, SMult32,
  18.  
  19. /*  SYNOPSIS */
  20.         __AROS_LHA(long, arg1, D0),
  21.         __AROS_LHA(long, arg2, D1),
  22.  
  23. /*  LOCATION */
  24.         struct UtilityBase *, UtilityBase, 23, Utility)
  25.  
  26. /*  FUNCTION
  27.         Performs the signed 32-bit multiplication of arg1 * arg2 and
  28.         returns a signed 32 bit value.
  29.  
  30.     INPUTS
  31.         arg1, arg2  -   32 bit signed longs
  32.  
  33.     RESULT
  34.         arg1 * arg2
  35.  
  36.     NOTES
  37.         This can perform the multiplication either using the machines
  38.         native instructions (if they exist), or in software using a
  39.         simple algorithm based on expanding algebraic products.
  40.  
  41.     EXAMPLE
  42.  
  43.         long a = 352543;
  44.         long b = -52464;
  45.         long c = SMult32(a,b);
  46.         c == -1315946768
  47.  
  48.     BUGS
  49.  
  50.     SEE ALSO
  51.         utility/UMult32(), utility/UMult64(), utility/SMult64()
  52.  
  53.     INTERNALS
  54.         We are performing the operation:
  55.  
  56.  
  57.             (2^16 * a + b) * (2^16 * c + d)
  58.           = 2^32 * ab + 2^16 * ad + 2^16 * bc + bd
  59.           = 2^32 * ab + 2^16 ( ad + bc ) + bd
  60.  
  61.         Now since the result is a 32-bit number, the 2^32 term will have
  62.         no effect. (Since 2^32 > max (32-bit number).
  63.  
  64.         Therefore:
  65.         product = 2^16( ad + bc ) + bd
  66.  
  67.     HISTORY
  68.         29-10-95    digulla automatically created from
  69.                             utility_lib.fd and clib/utility_protos.h
  70.         18-08-96    iaint   Implemented as described above.
  71.  
  72. *****************************************************************************/
  73. {
  74.     __AROS_FUNC_INIT
  75.  
  76. #ifdef HAS_32BITMULS
  77.     return arg1 * arg2;
  78. #else
  79.  
  80.     UWORD a1, b1, a0, b0;
  81.     BOOL neg;
  82.  
  83.     /* Fix everything up so that -ve signs don't vanish */
  84.     if(arg1 < 0)
  85.     {
  86.         neg = 1; arg1 = -arg1;
  87.     }
  88.     else
  89.         neg = 0;
  90.  
  91.     if(arg2 <= 0)
  92.     {
  93.         neg ^= 1; arg2 = -arg2;
  94.     }
  95.  
  96.     a1 = (arg1 >> 16) & 0xffff;
  97.     a0 = arg1 & 0xffff;
  98.     b1 = (arg2 >> 16) & 0xffff;
  99.     b0 = arg2 & 0xffff;
  100.  
  101.     arg1 = (((a0 * b1) + (a1 * b0)) << 16) + (b0 * a0);
  102.     return (neg ? -arg1 : arg1);
  103. #endif
  104.  
  105.     __AROS_FUNC_EXIT
  106. } /* SMult32 */
  107.